package com.difsonapps.android.marker.fragments;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.Cache;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.Cache.Entry;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.JsonObjectRequest;
import com.difsonapps.android.marker.AppConstant;
import com.difsonapps.android.marker.CustomRequest;
import com.difsonapps.android.marker.FormAlbumPhotosActivity;
import com.difsonapps.android.marker.IRefresher;
import com.difsonapps.android.marker.MainActivity;
import com.difsonapps.android.marker.R;
import com.difsonapps.android.marker.R.layout;
import com.difsonapps.android.marker.activities.FormVideoActivity;
import com.difsonapps.android.marker.activities.PhotoViewActivity;
import com.difsonapps.android.marker.adapters.PhotosGridAdapter;
import com.difsonapps.android.marker.app.AppController;
import com.difsonapps.android.marker.beans.Album;
import com.difsonapps.android.marker.beans.Photo;
import com.difsonapps.android.marker.beans.User;
import com.difsonapps.android.marker.beans.Video;
import com.difsonapps.android.marker.dialogs.DaoMenuActionsDialog;
import com.difsonapps.android.marker.dialogs.EditAlbumDialog;
import com.difsonapps.android.marker.dialogs.EditPhotoDialog;
import com.difsonapps.android.marker.dialogs.ViewAlbumDialog;
import com.difsonapps.android.marker.dialogs.ViewPhotoDialog;
import com.difsonapps.android.marker.fragments.AlbumsFragment.AlbumUpdateRefresher;
import com.difsonapps.android.marker.fragments.AlbumsFragment.MenuRefresher;
import com.difsonapps.android.marker.util.MarkerUtil;

import android.app.AlertDialog;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.MediaController;
import android.widget.PopupMenu;
import android.widget.Toast;

public class PhotosFragment extends Fragment {
	public static final String ARG_PARAM_ALBUM = "album";
	public static final String ARG_PARAM_MODE_PHOTO = "mode_photo";
    private static final String TAG = PhotosFragment.class.getSimpleName();
    private GridView gridView;
    private PhotosGridAdapter gridAdapter;
    PopupMenu popup;
    private ArrayList<Photo> photos;
    private ArrayList<Video> videos;
    private String URL_ALBUM = "http://10.0.2.2/putmark/public/home/photos";
    Album album;
    private boolean modePhotos = true;
	
	public PhotosFragment(){}
	
	public static PhotosFragment newInstance(Album album) {
		PhotosFragment fragment = new PhotosFragment();
		Bundle args = new Bundle();
		args.putParcelable(ARG_PARAM_ALBUM, album);
		fragment.setArguments(args);
		return fragment;
	}
	
	public static PhotosFragment newInstance(Album album, boolean modePhotos) {
		PhotosFragment fragment = new PhotosFragment();
		Bundle args = new Bundle();
		args.putParcelable(ARG_PARAM_ALBUM, album);
		args.putBoolean(ARG_PARAM_MODE_PHOTO, modePhotos);
		fragment.setArguments(args);
		return fragment;
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (getArguments() != null) {
			album = getArguments().getParcelable(ARG_PARAM_ALBUM);
			if(getArguments().containsKey(ARG_PARAM_MODE_PHOTO)){
				modePhotos = getArguments().getBoolean(ARG_PARAM_MODE_PHOTO, true);
			}
		}
	}
	
	
	
	@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
 
		
        View rootView = inflater.inflate(R.layout.fragment_photos, container, false);

		
		gridView = (GridView) rootView.findViewById(R.id.photosGridView);
		 
        photos = new ArrayList<Photo>();
        videos = new ArrayList<Video>();
 
        if(modePhotos) gridAdapter = new PhotosGridAdapter(this.getActivity(), photos);
        else gridAdapter = new PhotosGridAdapter(this.getActivity(), videos, false);
        
        gridView.setAdapter(gridAdapter);
        gridView.setColumnWidth(gridAdapter.getNewWidth());
        
        gridView.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View v,
					int position, long id) {
				Object object = gridAdapter.getItem(position);
				if(object instanceof Photo) showActionsPopupMenu((Photo)object, v);
				if(object instanceof Video) showActionsPopupMenu((Video)object, v);
				return true;
			}
        	
        });
        gridView.setOnItemClickListener(new OnItemClickListener() {
    		public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    			//Photo photo = (Photo)gridAdapter.getItem(position);
    			if(modePhotos) openPhoto(position);
    			else openVideo(position);
    			//toast("Selected photo at position "+position);
    			//Toast.makeText(MainActivity.this, position + "#Selected",Toast.LENGTH_SHORT).show();
    		}
     
        });
        
        load();
        
                
        return rootView;
    }
	private void openPhoto(Photo photo){
		int index = photos.indexOf(photo);
		if(index>=0) openPhoto(index);
	}
	private void openPhoto(int position){
		Intent intent = new Intent(getActivity(), PhotoViewActivity.class);
		Bundle b = new Bundle();
		b.putParcelableArrayList("photos", photos);
		b.putInt("position", position);
		intent.putExtras(b);
        startActivity(intent);
	}
	private void openVideo(Video video){
		int index = videos.indexOf(video);
		if(index>=0) openVideo(index);
	}
	private void openVideo(int position){
		Intent intent = new Intent(getActivity(), PhotoViewActivity.class);
		Bundle b = new Bundle();
		b.putParcelableArrayList("videos", videos);
		b.putInt("position", position);
		b.putBoolean("mode_photo", false);
		intent.putExtras(b);
        startActivity(intent);
	}
	
	ProgressDialog loadingProgressDialog;
	public void load(){
		if(modePhotos) loadPhotos();
		else loadVideos();
	}
	public void loadPhotos(){
		photos.clear();
		Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+(album!=null?album.getId():0));
        String url = MarkerUtil.buildUrl(AppConstant.photoUrl, params);
        Log.d(TAG, url);
        
        loadingProgressDialog = ProgressDialog.show(getActivity(), getResources().getString(R.string.loading), getResources().getString(R.string.load_photos_album_), true);
        loadingProgressDialog.setCancelable(true);
        Cache cache = AppController.getInstance().getRequestQueue().getCache();
        Entry entry = cache.get(url);
        if (entry != null) {
            // fetch the data from cache
            try {
                String data = new String(entry.data, "UTF-8");
                try {
                    parseJsonPhotos(new JSONObject(data));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
 
        } else {
            // making fresh volley request and getting json
            CustomRequest jsonReq = new CustomRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                                parseJsonPhotos(response);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
        }
	}
	
	private void parseJsonPhotos(JSONObject response) {
    	//toast("Response : "+response.toString());
        try {
            JSONArray feedArray = response.getJSONArray("photos");
            for (int i = 0; i < feedArray.length(); i++) {
                JSONObject feedObj = (JSONObject) feedArray.get(i);
                Photo item = Photo.parseFromJsonObject(feedObj);
                photos.add(item);
            }
            // notify data changes to list adapater
            gridAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if(loadingProgressDialog!=null) loadingProgressDialog.dismiss();
    }

	public void loadVideos(){
		photos.clear();
		Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+(album!=null?album.getId():0));
        String url = MarkerUtil.buildUrl(AppConstant.videoUrl, params);
        Log.d(TAG, url);
        
        loadingProgressDialog = ProgressDialog.show(getActivity(), getResources().getString(R.string.loading), getResources().getString(R.string.load_videos_album_), true);
        loadingProgressDialog.setCancelable(true);
        Cache cache = AppController.getInstance().getRequestQueue().getCache();
        Entry entry = cache.get(url);
        if (entry != null) {
            // fetch the data from cache
            try {
                String data = new String(entry.data, "UTF-8");
                try {
                	parseJsonVideos(new JSONObject(data));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
 
        } else {
            // making fresh volley request and getting json
            CustomRequest jsonReq = new CustomRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            //toast("Response : "+response.toString());
                            if (response != null) {
                            	parseJsonVideos(response);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
        }
	}
	
	private void parseJsonVideos(JSONObject response) {
    	//toast("Response : "+response.toString());
        try {
            JSONArray feedArray = response.getJSONArray("videos");
            for (int i = 0; i < feedArray.length(); i++) {
                JSONObject feedObj = (JSONObject) feedArray.get(i);
                Video item = Video.parseFromJsonObject(feedObj);
                videos.add(item);
                toast("Nb videos : "+videos.size());
            }
            // notify data changes to list adapater
            gridAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if(loadingProgressDialog!=null) loadingProgressDialog.dismiss();
    }

	public void addPhotos(List<Photo> photos){
		if(photos==null || photos.isEmpty()) return;
		this.photos.addAll(0, photos);
		//toast("Photo 1 src : "+photos.get(0).getImage());
		gridAdapter.notifyDataSetChanged();
	}

	public void addVideo(Video video){
		if(video==null) return;
		this.videos.add(0, video);
		gridAdapter.notifyDataSetChanged();
	}
	public void addVideos(List<Video> videos){
		if(videos==null || videos.isEmpty()) return;
		this.videos.addAll(0, videos);
		gridAdapter.notifyDataSetChanged();
	}
    
    public void showFormPhotos(boolean fromCamera){
    	if(!(getActivity() instanceof MainActivity)) return;
    	Intent intentCreateAlbum = new Intent(getActivity(), FormAlbumPhotosActivity.class);
    	Bundle b = new Bundle();
		b.putParcelable("album", album);
		b.putBoolean("from-camera", fromCamera);
		intentCreateAlbum.putExtras(b);
    	getActivity().startActivityForResult(intentCreateAlbum, MainActivity.ADD_PHOTOS);
    }
    
    public void showFormVideos(boolean fromCamera){
    	if(!(getActivity() instanceof MainActivity)) return;
    	Intent intentCreateAlbum = new Intent(getActivity(), FormVideoActivity.class);
    	Bundle b = new Bundle();
		b.putParcelable("album", album);
		b.putString(FormVideoActivity.KEY_MODE_VIDEO_PICKER, fromCamera?FormVideoActivity.MODE_CAMERA:FormVideoActivity.MODE_GALLERY);
		intentCreateAlbum.putExtras(b);
		getActivity().startActivityForResult(intentCreateAlbum, MainActivity.ADD_VIDEOS);
    }

    private void toast(String text){
		Toast.makeText(this.getActivity(), text, Toast.LENGTH_SHORT).show();
	}
    
    private void showActionsMenu(Photo photo){
    	if(menuRefresher==null) return;
    	menuRefresher.setPhoto(photo);
    	(new DaoMenuActionsDialog(getActivity(), menuRefresher, null)).show();
    }
    private void showActionsPopupMenu(Photo photo, View v){
    	popup = new PopupMenu(this.getActivity(), v);  
        popup.getMenuInflater().inflate(R.menu.album_popup_menu, popup.getMenu());
        if(menuRefresher==null) return;
    	menuRefresher.setPhoto(photo);
    	popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(android.view.MenuItem menuItem) {
                if(menuItem.getItemId()==R.id.edit_menu){
                	menuRefresher.refresh(DaoMenuActionsDialog.ACTION_EDIT);
                }else if(menuItem.getItemId()==R.id.view_menu){
                	menuRefresher.refresh(DaoMenuActionsDialog.ACTION_VIEW);
                }else if(menuItem.getItemId()==R.id.delete_menu){
                	menuRefresher.refresh(DaoMenuActionsDialog.ACTION_DELETE);
                }else if(menuItem.getItemId()==R.id.open_menu){
                	menuRefresher.refresh(DaoMenuActionsDialog.ACTION_OPEN);
                }else if(menuItem.getItemId()==R.id.cancel_menu){
                	
                }
                return false;
            }
        });
    	popup.show();
    }
    private void showActionsPopupMenu(Video video, View v){
    	popup = new PopupMenu(this.getActivity(), v);  
        popup.getMenuInflater().inflate(R.menu.album_popup_menu, popup.getMenu());
        if(videoMenuRefresher==null) return;
        videoMenuRefresher.setVideo(video);
    	popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(android.view.MenuItem menuItem) {
                if(menuItem.getItemId()==R.id.edit_menu){
                	videoMenuRefresher.refresh(DaoMenuActionsDialog.ACTION_EDIT);
                }else if(menuItem.getItemId()==R.id.view_menu){
                	videoMenuRefresher.refresh(DaoMenuActionsDialog.ACTION_VIEW);
                }else if(menuItem.getItemId()==R.id.delete_menu){
                	videoMenuRefresher.refresh(DaoMenuActionsDialog.ACTION_DELETE);
                }else if(menuItem.getItemId()==R.id.open_menu){
                	videoMenuRefresher.refresh(DaoMenuActionsDialog.ACTION_OPEN);
                }else if(menuItem.getItemId()==R.id.cancel_menu){
                	
                }
                return false;
            }
        });
    	popup.show();
    }
    
    private void loadEdit(Photo photo){
    	if(album!=null) (new EditPhotoDialog(getActivity(), photo, photoUpdateRefresher)).show();
    }
    private void loadEdit(Video video){
    	if(album!=null) (new EditPhotoDialog(getActivity(), video, videoUpdateRefresher)).show();
    }
    
    private void loadView(Photo photo){
    	if(album!=null) (new ViewPhotoDialog(getActivity(), photo, null)).show();
    }
    private void loadView(Video video){
    	if(album!=null) (new ViewPhotoDialog(getActivity(), video, null)).show();
    }
    private void loadDelete(final Photo photo){
    	new AlertDialog.Builder(getActivity())
    	.setTitle("Delete photo")
    	.setMessage("Do you really want to delete this photo?")
    	.setIcon(android.R.drawable.ic_dialog_alert)
    	.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
    	    public void onClick(DialogInterface dialog, int whichButton) {
    	    	startDelete(photo);
    	    }})
    	 .setNegativeButton(android.R.string.no, null).show();
    }
    public void startDelete(final Photo photo){
		if(photo==null) return;
		Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+photo.getId());
        String url = MarkerUtil.buildUrl(AppConstant.deletephotoUrl, params);
        Log.d(TAG, url);
        
        loadingProgressDialog = ProgressDialog.show(getActivity(), getResources().getString(R.string.loading), getResources().getString(R.string.deleting), true);
        loadingProgressDialog.setCancelable(true);
            // making fresh volley request and getting json
            CustomRequest jsonReq = new CustomRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                                parseJsonDeletePhoto(response, photo);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
	}
	
    private void parseJsonDeletePhoto(JSONObject response, Photo photo) {
    	//toast("Response : "+response.toString());
        try {
        	if(response.has("success")){
        		toast("Photo deleted");
        		photos.remove(photo);
        		gridAdapter.notifyDataSetChanged();
        	}else if(response.has("error")){
        		toast(""+response.getString("error"));
        	}else if(response.has("exception")){
        		toast("Exception");
        		Log.e(TAG, ""+response.getString("exception"));
        	}
            
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if(loadingProgressDialog!=null) loadingProgressDialog.dismiss();
    }
    
    private void loadDelete(final Video video){
    	new AlertDialog.Builder(getActivity())
    	.setTitle("Delete video")
    	.setMessage("Do you really want to delete this video?")
    	.setIcon(android.R.drawable.ic_dialog_alert)
    	.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

    	    public void onClick(DialogInterface dialog, int whichButton) {
    	    	startDelete(video);
    	    }})
    	 .setNegativeButton(android.R.string.no, null).show();
    }
    
    public void startDelete(final Video video){
		if(video==null) return;
		Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+video.getId());
        String url = MarkerUtil.buildUrl(AppConstant.deletevideoUrl, params);
        Log.d(TAG, url);
        
        loadingProgressDialog = ProgressDialog.show(getActivity(), getResources().getString(R.string.loading), getResources().getString(R.string.deleting), true);
        loadingProgressDialog.setCancelable(true);
            // making fresh volley request and getting json
            CustomRequest jsonReq = new CustomRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                                parseJsonDeleteVideo(response, video);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
	}
	
    private void parseJsonDeleteVideo(JSONObject response, Video video) {
    	//toast("Response : "+response.toString());
        try {
        	if(response.has("success")){
        		toast("Photo deleted");
        		videos.remove(video);
        		gridAdapter.notifyDataSetChanged();
        	}else if(response.has("error")){
        		toast(""+response.getString("error"));
        	}else if(response.has("exception")){
        		toast("Exception");
        		Log.e(TAG, ""+response.getString("exception"));
        	}
            
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if(loadingProgressDialog!=null) loadingProgressDialog.dismiss();
    }

    
    
    MenuRefresher menuRefresher = new MenuRefresher();
    MenuRefresher videoMenuRefresher = new MenuRefresher();
    class MenuRefresher implements IRefresher<Integer>{
    	Photo photo;
    	Video video;
		@Override
		public boolean refresh(Integer t) {
			if(t==DaoMenuActionsDialog.ACTION_EDIT){
				if(photo!=null) loadEdit(photo);
				else if(video!=null) loadEdit(video);
			}else if(t==DaoMenuActionsDialog.ACTION_VIEW){
				if(photo!=null) loadView(photo);
				else if(video!=null) loadView(video);
			}else if(t==DaoMenuActionsDialog.ACTION_DELETE){
				if(photo!=null) loadDelete(photo);
				else if(video!=null) loadDelete(video);
			}else if(t==DaoMenuActionsDialog.ACTION_OPEN){
				if(photo!=null) openPhoto(photo);
				else if(video!=null) openVideo(video);
			}
			return true;
		}
		public Photo getPhoto() {
			return photo;
		}
		public void setPhoto(Photo photo) {
			this.photo = photo;
		}
		public Video getVideo() {
			return video;
		}
		public void setVideo(Video video) {
			this.video = video;
		}
    }

    IRefresher<Photo> photoUpdateRefresher = new IRefresher<Photo>(){
		@Override
		public boolean refresh(Photo t) {
			replacePhoto(t);
			return false;
		}
    };
    
    IRefresher<Video> videoUpdateRefresher = new IRefresher<Video>(){
		@Override
		public boolean refresh(Video t) {
			replaceVideo(t);
			return false;
		}
    };
    private void replacePhoto(Photo photo){
    	int index = photos.indexOf(photo);
    	if(index>=0) {
    		photos.set(index, photo);
    		gridAdapter.notifyDataSetChanged();
    	}
    }
    private void replaceVideo(Video video){
    	int index = videos.indexOf(video);
    	if(index>=0) {
    		videos.set(index, video);
    		gridAdapter.notifyDataSetChanged();
    	}
    }
}
